using Microsoft.EntityFrameworkCore.Storage;
using WeatherSystem.API.Data;
using WeatherSystem.API.Models;
using WeatherSystem.API.Services;

namespace WeatherSystem.API.Repositories
{
    /// <summary>
    /// 工作单元实现
    /// </summary>
    public class UnitOfWork : IUnitOfWork
    {
        private readonly WeatherDbContext _context;
        private readonly ILogger<UnitOfWork> _logger;
        private readonly Dictionary<Type, object> _repositories;
        private IDbContextTransaction? _transaction;

        // 专用Repository实例
        private IWeatherDataReadRepository? _weatherDataReadRepository;
        private IWeatherDataWriteRepository? _weatherDataWriteRepository;
        private IReadRepository<User>? _userReadRepository;
        private IWriteRepository<User>? _userWriteRepository;
        private IReadRepository<City>? _cityReadRepository;
        private IWriteRepository<City>? _cityWriteRepository;
        private IReadRepository<StatisticsEntry>? _statisticsReadRepository;
        private IWriteRepository<StatisticsEntry>? _statisticsWriteRepository;

        private readonly ICacheService _cacheService;

        public UnitOfWork(WeatherDbContext context, ILogger<UnitOfWork> logger, ICacheService cacheService)
        {
            _context = context;
            _logger = logger;
            _cacheService = cacheService;
            _repositories = new Dictionary<Type, object>();
        }

        // 专用Repository属性
        public IWeatherDataReadRepository WeatherDataRead =>
            _weatherDataReadRepository ??= new WeatherDataReadRepository(_context, _logger as ILogger<WeatherDataReadRepository>, _cacheService);

        public IWeatherDataWriteRepository WeatherDataWrite =>
            _weatherDataWriteRepository ??= new WeatherDataWriteRepository(_context, _logger as ILogger<WeatherDataWriteRepository>, _cacheService as ICacheInvalidationService);

        public IReadRepository<User> UserRead =>
            _userReadRepository ??= new ReadRepository<User>(_context, _logger as ILogger<ReadRepository<User>>);

        public IWriteRepository<User> UserWrite =>
            _userWriteRepository ??= new WriteRepository<User>(_context, _logger as ILogger<WriteRepository<User>>);

        public IReadRepository<City> CityRead =>
            _cityReadRepository ??= new ReadRepository<City>(_context, _logger as ILogger<ReadRepository<City>>);

        public IWriteRepository<City> CityWrite =>
            _cityWriteRepository ??= new WriteRepository<City>(_context, _logger as ILogger<WriteRepository<City>>);

        public IReadRepository<StatisticsEntry> StatisticsRead =>
            _statisticsReadRepository ??= new ReadRepository<StatisticsEntry>(_context, _logger as ILogger<ReadRepository<StatisticsEntry>>);

        public IWriteRepository<StatisticsEntry> StatisticsWrite =>
            _statisticsWriteRepository ??= new WriteRepository<StatisticsEntry>(_context, _logger as ILogger<WriteRepository<StatisticsEntry>>);

        // 兼容性属性（逐步迁移使用）
        public IWeatherDataRepository WeatherData => new LegacyWeatherDataAdapter(WeatherDataRead, WeatherDataWrite);
        public IUserRepository Users => new LegacyUserAdapter(UserRead, UserWrite);
        public ICityRepository Cities => new LegacyCityAdapter(CityRead, CityWrite);
        public IStatisticsRepository Statistics => new LegacyStatisticsAdapter(StatisticsRead, StatisticsWrite);

        // 泛型Repository访问
        public IRepository<T> Repository<T>() where T : class
        {
            var type = typeof(T);
            if (!_repositories.ContainsKey(type))
            {
                // 使用新的读写分离架构
                if (typeof(T) == typeof(WeatherDataEntry))
                {
                    _repositories[type] = new WeatherDataReadRepository(_context, _logger as ILogger<WeatherDataReadRepository>, _cacheService);
                }
                else
                {
                    _repositories[type] = new ReadRepository<T>(_context, _logger as ILogger<ReadRepository<T>>);
                }
            }
            return (IRepository<T>)_repositories[type];
        }

        // 事务管理
        public async Task<int> SaveChangesAsync()
        {
            try
            {
                return await _context.SaveChangesAsync();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "保存更改时发生错误");
                throw;
            }
        }

        public async Task BeginTransactionAsync()
        {
            _transaction = await _context.Database.BeginTransactionAsync();
        }

        public async Task CommitTransactionAsync()
        {
            if (_transaction != null)
            {
                await _transaction.CommitAsync();
                _transaction.Dispose();
                _transaction = null;
            }
        }

        public async Task RollbackTransactionAsync()
        {
            if (_transaction != null)
            {
                await _transaction.RollbackAsync();
                _transaction.Dispose();
                _transaction = null;
            }
        }

        public void Dispose()
        {
            _transaction?.Dispose();
            _context.Dispose();
        }
    }
}